import { _decorator, Component, Node } from 'cc';
import CSV from '../3rd/CSVParser';
import { BaseClass } from './BaseClass';
const { ccclass, property } = _decorator;

/**
 * 初始化我们的Excel表格模块
 */
export class ExcelMgr extends BaseClass {
    private csvTables;  // "表格名字"---> object {key1(第一个字段): row1, ke2: row2}
    private csvTableForArr; // 表格名字---》array [row1, row2, row3,..]
    private tableCast; // 存放的是我们这个表格的类型
    private tableComment // 存放的是我们表格的注释;

    private static _inst: ExcelMgr;
    public static get inst(): ExcelMgr {
        if (this._inst == null) {
            this._inst = new ExcelMgr();
        }

        return this._inst;
    }

    constructor() {
        super()    
        this.csvTables = new Map()
        this.csvTableForArr = new Map()
        this.tableCast = new Map()
        this.tableComment = new Map()

        this.Init();
    }

    public Init(): void {

    }
 
    /**
     * 将.csv
     * @param tableName 
     * @param tableContent 
     * @param force 
     * @returns 
     */
    public AddTable (tableName:string, tableContent:string, force?:boolean) {
        if (this.csvTables.get(tableName) && !force) {
            return;
        }
 
        var tableData = new Map(); // 作为主键---》object 映射表
        var tableArr = []; // 所有数据放一个数组; 
        var opts = { header: true };
        CSV.parse(tableContent, opts, function (row, keyname) {
            tableData.set(row[keyname],row);
            tableArr.push(row);
        });
 
        this.tableCast.set(tableName,(CSV as any).opts.cast);
        this.tableComment.set(tableName,(CSV as any).opts.comment);
 
        this.csvTables.set(tableName, tableData);
        this.csvTableForArr.set(tableName, tableArr);
 
        // this.csvTables.get(tableName).initFromText(tableContent);
    }
 
    public GetTableArr (tableName:string) {
        return this.csvTableForArr.get(tableName);
    }
 
    public GetTable (tableName:string) {
        return this.csvTables.get(tableName);
    }
 
    /**
     * 获取一组数据
     * @param tableName 
     * @param value 
     * @returns 
     */
    public QueryOne (tableName:string, value:any): Object {
        var table = this.GetTable(tableName);
        if (!table) {
            return null;
        }
        return table.get(value)
    }
 
    QueryByID (tableName:string, ID:string) {
        // return this.QueryOne(tableName, null, ID);
    }
 
    QueryAll (tableName:string, key:string, value:any) {
        var table = this.GetTable(tableName);
        if (!table || !key) {
            return null;
        }
 
        var ret = {};
        for (var tbItem in table) {
            if (!table.hasOwnProperty(tbItem)) {
                continue;
            }
 
            if (table[tbItem][key] === value) {
                ret[tbItem] = table[tbItem];
            }
        }
        return ret;
    }
 
    public QueryIn (tableName:string, key:string, values:Array<any>) {
        var table = this.GetTable(tableName);
        if (!table || !key) {
            return null;
        }
 
        var ret = {};
        var keys = Object.keys(table);
        var length = keys.length;
        for (var i = 0; i < length; i++) {
            var item = table[keys[i]];
            if (values.indexOf(item[key]) > -1) {
                ret[keys[i]] = item;
            }
        }
 
        return ret;
    }
 
    QueryByCondition (tableName:string, condition: any) {
        if (condition.constructor !== Object) {
            return null;
        }
 
        var table = this.GetTable(tableName);
        if (!table) {
            return null;
        }
 
        var ret = {};
        var tableKeys = Object.keys(table);
        var tableKeysLength = tableKeys.length;
        var keys = Object.keys(condition);
        var keysLength = keys.length;
        for (var i = 0; i < tableKeysLength; i++) {
            var item = table[tableKeys[i]];
            var fit = true;
            for (var j = 0; j < keysLength; j++) {
                var key = keys[j];
                fit = fit && (condition[key] === item[key]) && !ret[tableKeys[i]];
            }
 
            if (fit) {
                ret[tableKeys[i]] = item;
            }
        }
 
        return ret;
    }
 
    QueryOneByCondition (tableName:string, condition: any) {
        if (condition.constructor !== Object) {
            return null;
        }
 
        var table = this.GetTable(tableName);
        if (!table) {
            return null;
        }
        
        var keys = Object.keys(condition);
        var keysLength = keys.length;
 
        for (let keyName in table) {
            var item = table[keyName];
 
            var fit = true;
            for (var j = 0; j < keysLength; j++) {
                var key = keys[j];
                fit = fit && (condition[key] === item[key]);
            }
 
            if (fit) {
                return item;
            }
        }
 
        return null;
    }
}


